package com.ruoyi.wechat.util;

import com.ruoyi.wechat.WeChatPay;
import com.ruoyi.wechat.pay.PayWeChat;
import com.ruoyi.wechat.pay.ToPayByOpenid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

@Component
public class PayUtil {
	@Autowired
	private WeChatPay weChatPay;
	/**
	 * @Description: TODO(生成随机字符串)
	 * @author cuihang
	 * @date 2015-10-12 下午1:56:27
	 * @param length
	 * @return
	 */
	public static String getRandomString(int length) { // length表示生成字符串的长度
		String base = "abcdefghijklmnopqrstuvwxyz0123456789";
		Random random = new Random();
		StringBuffer sb = new StringBuffer();
		int baslength=base.length();
		for (int i = 0; i < length; i++) {
			int number = random.nextInt(baslength);
			sb.append(base.charAt(number));
		}
		return sb.toString();
	}
	public static String getRandomLong(int length) { // length表示生成字符串的长度
		String base = "0123456789";
		Random random = new Random();
		StringBuffer sb = new StringBuffer();
		int baslength=base.length();
		for (int i = 0; i < length; i++) {
			int number = random.nextInt(baslength);
			sb.append(base.charAt(number));
		}
		return sb.toString();
	}

	/**
	 * @Description: TODO(得到生成订单的签名字符串)
	 * @author cuihang
	 * @date 2015-10-13 下午2:18:12
	 * @param ow
	 * @return
	 */
	public  String getOrderWeChatSignStr(Object ow) {
		StringBuffer result = new StringBuffer();
		List list = new ArrayList();
		Map keyV = new HashMap();
		String get = "get";
		Class class1 = ow.getClass();
		Method[] methods = class1.getMethods();
		for (Method method : methods) {
			String methodName = method.getName();
			if (methodName.startsWith(get)) {
				String propertyName = methodName.substring(3).toLowerCase(Locale.getDefault());
				// Object value = map.get(propertyName);
				try {
					if (!propertyName.equals("sign") && !propertyName.equals("class") && method.invoke(ow) != null && method.invoke(ow).toString().length() > 0) {
						list.add(propertyName);
						keyV.put(propertyName, method.invoke(ow));
					}
				} catch (IllegalArgumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		Object array[] = (Object[]) list.toArray();
		Arrays.sort(array);
		int num = 0;
		for (Object key : array) {

			if (num == 0) {
				result.append(key).append("=").append(keyV.get(key));

			} else {
				result.append("&").append(key).append("=").append(keyV.get(key));

			}
			num++;
		}
		result.append("&").append("key=").append(weChatPay.getApiSecret());
		return result.toString();
	}
	/**
	 *
	*@Description: TODO(用一句话描述该文件做什么)
	* @author cuihang
	*@date 2015-11-9 下午6:49:26
	*@return
	 */
	public  String getToPayByOpenidSignStr(ToPayByOpenid tpbo, String APPKEY) {
		StringBuffer result = new StringBuffer();
		List list = new ArrayList();
		Map keyV = new HashMap();
		String get = "get";
		Class class1 = tpbo.getClass();
		Method[] methods = class1.getMethods();
		for (Method method : methods) {
			String methodName = method.getName();
			if (methodName.startsWith(get)) {
				String propertyName = methodName.substring(3).toLowerCase(Locale.getDefault());
				// Object value = map.get(propertyName);
				try {
					if (!propertyName.equals("sign") && !propertyName.equals("class") && method.invoke(tpbo) != null && method.invoke(tpbo).toString().length() > 0) {
						list.add(propertyName);
						keyV.put(propertyName, method.invoke(tpbo));
					}
				} catch (IllegalArgumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		Object array[] = (Object[]) list.toArray();
		Arrays.sort(array);
		int num = 0;
		for (Object key : array) {

			if (num == 0) {
				result.append(key).append("=").append(keyV.get(key));

			} else {
				result.append("&").append(key).append("=").append(keyV.get(key));

			}
			num++;
		}
		result.append("&").append("key=").append(weChatPay.getApiSecret());
		return result.toString();
	}
	/**
	 * @Description: TODO(得到发起支付签名)
	 * @author cuihang
	 * @date 2015-10-13 下午2:42:03
	 * @param pw
	 * @return
	 */
	public  String getPayWeChatSignStr(PayWeChat pw) {
		StringBuffer result = new StringBuffer();
		List list = new ArrayList();
		Map keyV = new HashMap();
		String get = "get";
		Class class1 = pw.getClass();
		Method[] methods = class1.getMethods();
		for (Method method : methods) {
			String methodName = method.getName();
			if (methodName.startsWith(get)) {
				String propertyName = methodName.substring(3).toLowerCase(Locale.getDefault());
				if(propertyName.equals("prepay_id")){
					propertyName="package";
				}
				if(propertyName.equals("appid")){
					propertyName="appId";
				}
				if(propertyName.equals("timestamp")){
					propertyName="timeStamp";
				}
				if(propertyName.equals("noncestr")){
					propertyName="nonceStr";
				}
				if(propertyName.equals("signtype")){
					propertyName="signType";
				}
				// Object value = map.get(propertyName);
				try {
					if (!propertyName.equals("paysign") && !propertyName.equals("class") && method.invoke(pw) != null && method.invoke(pw).toString().length() > 0) {
						list.add(propertyName);
						keyV.put(propertyName, method.invoke(pw));
					}
				} catch (IllegalArgumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		Object array[] = (Object[]) list.toArray();
		Arrays.sort(array);
		int num = 0;
		for (Object key : array) {

			if (num == 0) {
				result.append(key).append("=").append(keyV.get(key));

			} else {
				result.append("&").append(key).append("=").append(keyV.get(key));

			}
			num++;
		}
		 result.append("&").append("key=").append(weChatPay.getApiSecret());
		return result.toString();
	}
	/**
	 * @Description: TODO(获取ip地址)
	 * @author cuihang
	 * @date 2015-10-12 下午2:18:28
	 * @param request
	 * @return
	 */
	public static String getIpAddr(HttpServletRequest request) {
		String ipAddress = request.getHeader("x-forwarded-for");
		if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getHeader("Proxy-Client-IP");
		}
		if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getRemoteAddr();
			if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {
				// 根据网卡取本机配置的IP
				InetAddress inet = null;
				try {
					inet = InetAddress.getLocalHost();
				} catch (UnknownHostException e) {
					e.printStackTrace();
				}
				ipAddress = inet.getHostAddress();
			}
		}
		// 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
		if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length() = 15
			if (ipAddress.indexOf(",") > 0) {
				ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
			}
		}
		return ipAddress;
	}

	/**
	 * @Description: TODO(根据str进行生成签名)
	 * @author cuihang
	 * @date 2015-10-13 下午2:18:41
	 * @param str
	 * @return
	 */
	public static String checkSignature(String str) {
		String[] arr = { str };

		Arrays.sort(arr);
		StringBuilder content = new StringBuilder();
		for (int i = 0; i < arr.length; i++) {
			content.append(arr[i]);
		}
		MessageDigest md = null;
		String tmpStr = null;
		try {
			md = MessageDigest.getInstance("MD5");

			byte[] digest = md.digest(content.toString().getBytes());
			tmpStr = byteToStr(digest);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}

		content = null;

		return tmpStr.toUpperCase(Locale.getDefault());
	}

	private static String byteToStr(byte[] byteArray) {
		String strDigest = "";
		for (int i = 0; i < byteArray.length; i++) {
			strDigest = strDigest + byteToHexStr(byteArray[i]);
		}
		return strDigest;
	}

	private static String byteToHexStr(byte mByte) {
		char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
		char[] tempArr = new char[2];
		tempArr[0] = Digit[(mByte >>> 4 & 0xF)];
		tempArr[1] = Digit[(mByte & 0xF)];

		String s = new String(tempArr);
		return s;
	}

	/**
	 * @Description: TODO(返回对象对应xml)
	 * @author cuihang
	 * @date 2015-10-13 下午2:19:14
	 * @param obj
	 * @return
	 */
	public static String getStringxML(Object obj) {
		StringBuffer result = new StringBuffer("<xml>");
		String get = "get";
		Class class1 = obj.getClass();
		Method[] methods = class1.getMethods();
		for (Method method : methods) {
			String methodName = method.getName();
			if (methodName.startsWith(get)) {
				String propertyName = methodName.substring(3).toLowerCase(Locale.getDefault());
				// Object value = map.get(propertyName);
				try {
					if (!propertyName.equals("class") && method.invoke(obj) != null && method.invoke(obj).toString().length() > 0) {
						result.append("<").append(propertyName).append(">");
						result.append(method.invoke(obj));
						result.append("</").append(propertyName).append(">");
					}
				} catch (IllegalArgumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		result.append("</xml>");
		return result.toString();
	}
}
